/* Copyright 203-2115 AtomWare Technology Pty Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 * The flowing information must be keep 
 * ClientTemplate.java
 * netsystem
 * 2013年11月7日上午8:20:34
 * @author 屈甲康
 * QQ285799123
 * mailto:qujiakang@gmail.com
 */

package org.jackysoft.net.ftpserver;

import java.io.File;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.net.ProtocolCommandEvent;
import org.apache.commons.net.ProtocolCommandListener;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPConnectionClosedException;
import org.apache.ftpserver.ConnectionConfigFactory;
import org.apache.ftpserver.DataConnectionConfigurationFactory;
import org.apache.ftpserver.FtpServerFactory;
import org.apache.ftpserver.impl.DefaultFtpServer;
import org.apache.ftpserver.impl.FtpIoSession;
import org.apache.ftpserver.listener.ListenerFactory;
import org.apache.ftpserver.usermanager.ClearTextPasswordEncryptor;
import org.apache.ftpserver.usermanager.PropertiesUserManagerFactory;

public class ClientTemplate {
	private final Log LOG = LogFactory.getLog(ClientTemplate.class);

	protected static final String ADMIN_PASSWORD = "admin";

	protected static final String ADMIN_USERNAME = "admin";	

	protected DefaultFtpServer server;

	protected FTPClient client;

	private static final File USERS_FILE = new File("myusers.properties");

	private static final File TEST_TMP_DIR = new File("test-tmp");

	protected static final File ROOT_DIR = new File(TEST_TMP_DIR, "ftproot");

	protected FtpServerFactory createServerFactory() throws Exception {		

		FtpServerFactory serverFactory = new FtpServerFactory();

		serverFactory.setConnectionConfig(createConnectionConfigFactory()
				.createConnectionConfig());

		ListenerFactory listenerFactory = new ListenerFactory();

		listenerFactory.setPort(0);

		listenerFactory
				.setDataConnectionConfiguration(createDataConnectionConfigurationFactory()
						.createDataConnectionConfiguration());

		serverFactory.addListener("default", listenerFactory.createListener());

		PropertiesUserManagerFactory umFactory = new PropertiesUserManagerFactory();
		umFactory.setAdminName("admin");
		umFactory.setPasswordEncryptor(new ClearTextPasswordEncryptor());
		umFactory.setFile(USERS_FILE);

		serverFactory.setUserManager(umFactory.createUserManager());

		return serverFactory;
	}

	protected ConnectionConfigFactory createConnectionConfigFactory() {
		return new ConnectionConfigFactory();
	}

	protected DataConnectionConfigurationFactory createDataConnectionConfigurationFactory() {
		return new DataConnectionConfigurationFactory();
	}

	protected int getListenerPort() {
		return server.getListener("default").getPort();
	}

	protected boolean isStartServer() {
		return true;
	}

	protected FTPClient createFTPClient() throws Exception {
		FTPClient client = new FTPClient();
		client.setDefaultTimeout(10000);
		return client;
	}

	/**
	 * @throws Exception
	 */
	protected void connectClient() throws Exception {
		client = createFTPClient();
		client.addProtocolCommandListener(new ProtocolCommandListener() {

			public void protocolCommandSent(ProtocolCommandEvent event) {
				LOG.debug("> " + event.getMessage().trim());

			}

			public void protocolReplyReceived(ProtocolCommandEvent event) {
				LOG.debug("< " + event.getMessage().trim());
			}
		});

		if (isConnectClient()) {
			doConnect();
		}
	}

	protected void doConnect() throws Exception {
		try {
			client.connect("localhost", getListenerPort());
		} catch (FTPConnectionClosedException e) {
			// try again
			Thread.sleep(200);
			client.connect("localhost", getListenerPort());
		}
	}

	protected boolean isConnectClient() {
		return true;
	}
	

	protected FtpIoSession getActiveSession() {
		return server.getListener("default").getActiveSessions().iterator()
				.next();
	}
	
}
